#pragma once
#include <iostream>
#include <vector>
#include <functional>
#include <unordered_map>
#include <memory>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <cassert>
#include <cstring>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <sys/epoll.h>
#include <sys/eventfd.h>
#include <sys/timerfd.h>
#include <signal.h>

// ##表示后面的不定参数可要可不要

#define INF 0
#define DBG 1
#define ERR 2
#define LOG_LEVEL ERR
#define Log(level, format, ...)                                                                               \
    do                                                                                                        \
    {                                                                                                         \
        if (level < LOG_LEVEL)                                                                                \
            break;                                                                                            \
        time_t t = time(nullptr);                                                                             \
        struct tm *ltm = localtime(&t);                                                                       \
        char tmp[32] = {0};                                                                                   \
        strftime(tmp, 31, "%H:%M:%S", ltm);                                                                   \
        printf("[%p %s %s:%d] " format "\n", (void *)pthread_self(), tmp, __FILE__, __LINE__, ##__VA_ARGS__); \
    } while (0)

#define INF_LOG(format, ...) Log(INF, format, ##__VA_ARGS__);
#define DBG_LOG(format, ...) Log(DBG, format, ##__VA_ARGS__);
#define ERR_LOG(format, ...) Log(ERR, format, ##__VA_ARGS__);

#define BUFFER_DEFAULT_SIZE 1024

class Any
{
private:
    class PlaceHolder
    {
    public:
        virtual ~PlaceHolder() {}
        virtual const std::type_info &Type() = 0;
        virtual PlaceHolder *Clone() = 0;
    };

    template <class T>
    class Holder : public PlaceHolder
    {
    public:
        ~Holder() {}
        Holder(const T &val) : val_(val) {}

        // 返回的类型为：const std::type_info&
        const std::type_info &Type() { return typeid(T); }

        PlaceHolder *Clone() { return new Holder(val_); }

    public:
        T val_;
    };

    PlaceHolder *content_;

public:
    Any() : content_(nullptr) {}
    template <class T>
    Any(const T &val) { content_ = new Holder<T>(val); }
    Any(const Any &other):content_(other.content_ ? other.content_->Clone() : nullptr)
    {}
    ~Any()
    {
        if (content_)
            delete content_;
    }

    template <class T>
    T *Get()
    {
        if (typeid(T) != content_->Type())
        {
            return nullptr;
        }

        return &((Holder<T> *)content_)->val_;
    }

    void Swap(Any &other)
    {
        PlaceHolder *tmp = other.content_;
        other.content_ = content_;
        content_ = tmp;
    }

    template <class T>
    Any &operator=(const T &val)
    {
        Any(val).Swap(*this);
        return *this;
    }

    Any &operator=(const Any &other)
    {
        Any(other).Swap(*this);
        return *this;
    }
};

class Buffer
{
private:
    // 存放数据的地方，不用string存放得主要原因是string不能存发'\0'字符
    // 而且string一般是操作字符串类型，不适用其他类型得存储
    std::vector<char> buffer_;
    // 写的偏移
    uint64_t writer_index_;
    // 读的偏移
    uint64_t reader_index_;

public:
    Buffer() : writer_index_(0), reader_index_(0), buffer_(BUFFER_DEFAULT_SIZE)
    {
    }

    char *Begin()
    {
        return &buffer_[0];
    }

    // 获取读的位置（不用void*是因为其不能算步长）
    char *ReadPosition()
    {
        return Begin() + reader_index_;
    }

    // 获取写的位置（不用void*是因为其不能算步长）
    char *WritePosition()
    {
        return Begin() + writer_index_;
    }

    // 起始位置开始闲置的空间大小
    uint64_t HeadIdleSpace()
    {
        return reader_index_;
    }

    // 末尾闲置的空间大小
    uint64_t TailIdleSpace()
    {
        return buffer_.size() - writer_index_;
    }

    // 可读数据区的大小
    uint64_t ReadableSize()
    {
        return writer_index_ - reader_index_;
    }

    // 确认是否可以写入那么len长的数据，可以就直接写入，不能就扩容或者移数据
    void EnsureWriteSpace(uint64_t len)
    {
        // 末尾位置够直接返回
        if (len <= TailIdleSpace())
        {
            return;
        }
        else
        {
            // 末尾位置不够但是总体剩余空间够，移动数据
            if (len <= TailIdleSpace() + HeadIdleSpace())
            {
                uint64_t read_size = ReadableSize();
                char *pos = ReadPosition();
                std::copy(pos, pos + read_size, Begin());
                // 这里有个细节，readableSize的值需要两个变量的原值，因此先改变wirte偏移，再改变读偏移
                writer_index_ = read_size;
                reader_index_ = 0;
            }
            // 扩容
            else
            {
                DBG_LOG("RESIZE %ld", writer_index_ + len);
                // 从写偏移向后扩容len个长度即可
                buffer_.resize(writer_index_  + len);
            }
        }
    }

    // 读取数据后读偏移的移动
    void MoveReaderOffset(uint64_t len)
    {
        assert(len <= ReadableSize());
        reader_index_ += len;
    }

    // 写入数据后写偏移的移动
    void MoveWriterOffset(uint64_t len)
    {
        //移动长度必须小于后面空闲空间大小
        assert(len <= TailIdleSpace());
        writer_index_ += len;
    }

    // 三个主要接口:读\写\清除

    // 写入数据
    void Write(const void *data, uint64_t len)
    {
        EnsureWriteSpace(len);

        const char *d = (const char *)data;
        std::copy(d, d + len, WritePosition());
    }

    void WriteAndPush(const void *data, uint64_t len)
    {
        Write(data, len);
        MoveWriterOffset(len);
    }

    // 读取数据
    void Read(void *buf, uint64_t len)
    {
        assert(len <= ReadableSize());

        // copy实际要求传入的是迭代器，我们传入指针作为迭代器时必须是合法的
        // void*是肯定不能变为迭代器，它是没有步长的
        std::copy(ReadPosition(), ReadPosition() + len, (char *)buf);
    }

    void ReadAndPop(void *buf, uint64_t len)
    {
        Read(buf, len);
        MoveReaderOffset(len);
    }

    // 清理数据
    void ClearBuffer()
    {
        writer_index_ = 0;
        reader_index_ = 0;
    }

    // 针对不同类型调整读、写
    void WriteStringAndPush(const std::string &str)
    {
        WriteString(str);
        MoveWriterOffset(str.size());
    }

    void WriteString(const std::string &str)
    {
        Write(str.c_str(), str.size());
    }

    void WriteBuffer(Buffer &buf)
    {
        Write(buf.ReadPosition(), buf.ReadableSize());
    }

    void WriteBufferAndPush(Buffer &buf)
    {
        WriteBuffer(buf);
        MoveWriterOffset(buf.ReadableSize());
    }

    std::string ReadAsStringAndPop(uint64_t len)
    {
        std::string ret;
        ret = ReadAsString(len);
        MoveReaderOffset(len);
        return ret;
    }

    std::string ReadAsString(uint64_t len)
    {
        assert(len <= ReadableSize());
        std::string ret;
        ret.resize(len);
        Read(&ret[0], len);
        return ret;
    }

    // 找到回车换行的位置
    char *FindCRLF()
    {
        char *pos = (char *)memchr(ReadPosition(), '\n', ReadableSize());
        return pos;
    }

    // 获取一行内容，主要是为了http协议写的。
    // 而且如果是按行输入的数据，一般都是ASCII编码的数据，是可见字符，所以返回string类型
    std::string GetLine()
    {
        char *pos = FindCRLF();
        if (pos == nullptr)
        {
            return "";
        }

        // 指针和指针相减是整数值
        return ReadAsString(pos - ReadPosition() + 1);
    }

    std::string GetLineAndPop()
    {
        std::string ret;
        ret = GetLine();
        MoveReaderOffset(ret.size());
        return ret;
    }
};

#define DEFAULT_BACKLOG_SIZE 1024

class Socket
{
private:
    int sockfd_;

public:
    Socket() : sockfd_(-1)
    {
    }
    Socket(int newfd) : sockfd_(newfd)
    {
    }
    ~Socket()
    {
        Close();
    }

    // 获取fd
    int GetFd()
    {
        return sockfd_;
    }

    // 关闭套接字
    void Close()
    {
        if (sockfd_ != -1)
        {
            close(sockfd_);
            sockfd_ = -1;
        }
    }

    // 创建套接字
    bool Create()
    {
        int sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        if (sockfd < 0)
        {
            ERR_LOG("CREATE SOCKET FAILED!!");
            return false;
        }
        sockfd_ = sockfd;

        return true;
    }

    // 绑定套接字
    bool Bind(const std::string &ip, const uint16_t &port)
    {
        struct sockaddr_in addr;
        addr.sin_family = AF_INET;
        addr.sin_port = htons(port);
        addr.sin_addr.s_addr = inet_addr(ip.c_str());

        socklen_t len = sizeof(addr);
        int n = bind(sockfd_, (struct sockaddr *)&addr, len);
        if (n < 0)
        {
            ERR_LOG("SOCKET BIND FAILED!!");
            return false;
        }

        return true;
    }

    // 监听套接字
    bool Listen(int backlog = DEFAULT_BACKLOG_SIZE)
    {
        int n = listen(sockfd_, backlog);
        if (n < 0)
        {
            ERR_LOG("SOCKET LISTEN FAILED!!");
            return false;
        }

        return true;
    }

    // 连接服务器
    bool Connect(const std::string &ip, const uint16_t &port)
    {
        struct sockaddr_in addr;
        addr.sin_family = AF_INET;
        addr.sin_port = htons(port);
        addr.sin_addr.s_addr = inet_addr(ip.c_str());

        socklen_t len = sizeof(addr);
        int n = connect(sockfd_, (struct sockaddr *)&addr, len);
        if (n < 0)
        {
            ERR_LOG("SOCKET CONNECT FAILED!!");
            return false;
        }
        return true;
    }

    // 获取新连接
    int Accept()
    {
        // 后两个参数用来接收客户端的协议地址与长度，我们这里用不上
        int newfd = accept(sockfd_, nullptr, nullptr);
        if (newfd < 0)
        {
            ERR_LOG("SOCKET ACCEPT FAILED!!");
            return -1;
        }
        return newfd;
    }

    // 0表示阻塞
    ssize_t Send(const void *buf, size_t len, int flag = 0)
    {
        //// ssize_t send(int sockfd, void *data, size_t len, int flag);
        ssize_t n = send(sockfd_, buf, len, flag);
        if (n < 0)
        {
            // 前一错误只有设置为非阻塞才会产生
            if (errno == EAGAIN || errno == EINTR)
            {
                return 0;
            }
            else
            {
                ERR_LOG("SOCKET SEND FAILED!!");
                return -1;
            }
        }
        return n;
    }

    // 非阻塞发送
    ssize_t SendNoneBlock(const void *buf, size_t len)
    {
        return Send(buf, len, MSG_DONTWAIT); //MSG_DONTWAIT 表示当前发送为非阻塞。
    }

    // 0表示阻塞
    ssize_t Recv(void *buf, size_t len, int flag = 0)
    {
        ssize_t n = recv(sockfd_, buf, len, flag);
        if (n <= 0)
        {
            // EAGAIN 当前socket的接收缓冲区中没有数据了，在⾮阻塞的情况下才会有这个错误
            // EINTR 表⽰当前socket的阻塞等待，被信号打断了，
            if (errno == EAGAIN || errno == EINTR)
            {
                return 0;
            }
            else
            {
                ERR_LOG("SOCKET RECV FAILED!!");
                return -1;
            }
        }

        return n;
    }
    // 非阻塞读取
    ssize_t RecvNoneBlock(void *buf, size_t len)
    {
        return Recv(buf, len, MSG_DONTWAIT);// MSG_DONTWAIT 表示当前接收为非阻塞
    }

    // 开启地址端口复用
    void ReuseAddress()
    {
        // int setsockopt(int fd, int leve, int optname, void *val, int vallen)
        int val = 1;
        int n = setsockopt(sockfd_, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &val, sizeof(val));
        if (n < 0)
        {
            ERR_LOG("SOCKET SETOPT FAILED!!");
        }
    }
    // 开启非阻塞
    void SetNonBlock()
    {
        // int fcntl(int fd, int cmd, ... /* arg */ )
        int fl = fcntl(sockfd_, F_GETFL);
        int n = fcntl(sockfd_, F_SETFL, fl | O_NONBLOCK);
        if (n < 0)
        {
            ERR_LOG("SOCKET SETNONBLOCK FAILED!!");
        }
    }

    // 构造一个tcp服务器
     // 如果server端操作系统内有多个网卡（每个网卡上有不同的IP地址）\
    可以要在调用bind()的时候，告诉操作系统：“我需要在 yyyy 端口上侦听，所有发送到服务器的这个端口，不管是哪个网卡/哪个IP地址接收到的数据，都是我处理的。”这时候，服务器程序则在0.0.0.0这个地址上进行侦听

    bool CreateServer(const uint16_t &port, const std::string &ip = "0.0.0.0", bool set_non_block = false)
    {
        if (Create() == false)
            return false;
        if (set_non_block)
            SetNonBlock();

        // 地址复用必须在bind前告知系统
        ReuseAddress();
        if (Bind(ip, port) == false)
            return false;
        if (Listen() == false)
            return false;

        // DBG_LOG("SERVER CREATE SUCCESS!!");
        return true;
    }

    // 构造一个tcp客户端连接
    bool CreateClient(const uint16_t &port, const std::string &ip)
    {
        if (Create() == false)
            return false;
        if (Connect(ip, port) == false)
            return false;

        DBG_LOG("CLIENT CREATE SUCCESS!!");
        return true;
    }
};

// 声明Poller模块
class Poller;
// 声明EventLoop模块
class EventLoop;

// 声明了Poller类但还是不知道Poller里面的成员方法，还是会报错
class Channel
{
private:
    using EventCallback = std::function<void()>;
    // 监听的事件
    uint32_t events_;
    // 触发的事件
    uint32_t trigger_events_;
    // 监听的描述符
    int fd_;

    // 以后是EventLoop模块对我们的Poller模块进行管理
    EventLoop *loop_;

    // 写事件回调
    EventCallback write_callback_;
    // 读事件回调
    EventCallback read_callback_;
    // 错误事件回调
    EventCallback error_callback_;
    // 断开连接事件回调
    EventCallback disconnect_callback_;
    // 任意事件回调
    EventCallback any_callback_;

public:
    Channel(EventLoop *loop, int fd) : fd_(fd), events_(0), loop_(loop),trigger_events_(0)
    {
    }
    // 获取监听的事件
    uint32_t GetEvents()
    {
        return events_;
    }
    // 设置活跃的事件
    void SetTriEvents(uint32_t events)
    {
        trigger_events_ = events;
    }
    // 获取描述符
    int GetFd()
    {
        return fd_;
    }
    // 是否监听读事件
    bool IsListenRead()
    {
        return events_ & EPOLLIN;
    }
    // 是否监听写事件
    bool IsListenwrite()
    {
        return events_ & EPOLLOUT;
    }
    // 开启读事件监听
    void EnableReadListen()
    {
        events_ |= EPOLLIN;
        // 后面还要添加到EventLoop的监听事件中，这里只是加载到用户态中，没有起作用
        UpdateListen();
    }
    // 开启写事件监听
    void EnableWriteListen()
    {
        events_ |= EPOLLOUT;
        // 后面还要添加到EventLoop的监听事件中，这里只是加载到用户态中，没有起作用
        UpdateListen();
    }
    // 关闭读事件监听
    void DisableReadListen()
    {
        events_ &= ~EPOLLIN;
        // 后面还要添加到EventLoop的监听事件中，这里只是加载到用户态中，没有起作用
        UpdateListen();
    }
    // 关闭写事件监听
    void DisableWriteListen()
    {
        events_ &= ~EPOLLOUT;
        // 后面还要添加到EventLoop的监听事件中，这里只是加载到用户态中，没有起作用
        UpdateListen();
    }
    // 取消所有事件监听
    void CancleEveryListen()
    {
        events_ = 0;
        // 后面还要添加到EventLoop的监听事件中，这里只是加载到用户态中，没有起作用
        UpdateListen();
    }
    // 移除监听
    // 这个在EventLoop中完成，在epoll管理的红黑树上移除我们的连接监控
    void RemoveListen();

    // 更改事件监听
    void UpdateListen();

    // 设置写事件回调
    void SetWriteCallback(const EventCallback &cb)
    {
        write_callback_ = cb;
    }
    // 设置读事件回调
    void SetReadCallback(const EventCallback &cb)
    {
        read_callback_ = cb;
    }
    // 设置错误事件回调
    void SetErrorCallback(const EventCallback &cb)
    {
        error_callback_ = cb;
    }
    // 设置断开连接事件回调
    void SetDisconnectCallback(const EventCallback &cb)
    {
        disconnect_callback_ = cb;
    }
    // 设置任意事件回调
    void SetAnyCallback(const EventCallback &cb)
    {
        any_callback_ = cb;
    }

    // 事件触发后调用的函数，帮我们处理各个事件
    void HandleEvents()
    {

        //写事件、错误事件、断开连接事件应该只处理一个，如果都同时处理，写发生错误断开连接，再去断开连接\
        就会发生错误导致程序崩溃。

        // 读写事件如果出错断开连接了，那么也不刷新活跃度了
        if ((trigger_events_ & EPOLLIN) || (trigger_events_ & EPOLLPRI) || (trigger_events_ & EPOLLRDHUP))
        {
            if (read_callback_)
                read_callback_();
        }
        // 如果channel对象被释放了，下面的事情就不用做了
        if (trigger_events_ & EPOLLOUT)
        {
            if (write_callback_)
                write_callback_();
        }
        else if (trigger_events_ & EPOLLHUP)
        {
            if (disconnect_callback_)
                disconnect_callback_();
        }
        else if (trigger_events_ & EPOLLERR)
        {
            if (error_callback_)
                error_callback_();
        }
        // 刷新连接活跃度在断开连接之前
        if (any_callback_)
            any_callback_();
    }
};

#define MAX_EPOLL_SIZE 1024

class Poller
{
private:
    // epoll的描述符
    int epfd_;
    // 存储活跃的事件
    struct epoll_event events_[MAX_EPOLL_SIZE];
    // 存储连接描述符和channel对象的联系
    std::unordered_map<int, Channel *> channels_;

private:
    // 对epoll的直接操作
    void Update(Channel *channel, int op)
    {
        int fd = channel->GetFd();
        struct epoll_event events;
        events.data.fd = fd;
        events.events = channel->GetEvents();
        //  int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
        int n = epoll_ctl(epfd_, op, fd, &events);
        if (n < 0)
        {
            ERR_LOG("%d:%s",fd,strerror(errno));
            ERR_LOG("n: %d",n);
            ERR_LOG("EPOLLCTL FAILED!!");
        }
    }

    // 查询channel对象是否添加到监听
    bool HasChannel(Channel *channel)
    {
        int fd = channel->GetFd();
        auto it = channels_.find(fd);
        if (it == channels_.end())
        {
            return false;
        }
        return true;
    }

public:
    Poller()
    {
        // 最大监听数量，但是现在设置啥都没影响，不影响监听数量
        //   int epoll_create(int size);
        int epfd = epoll_create(MAX_EPOLL_SIZE);
        if (epfd < 0)
        {
            ERR_LOG("EPOLL CRREATE FAILED!!, % s", strerror(errno));
            abort();
        }
        epfd_ = epfd;
    }

    // 添加/更新事件的监控
    void UpdateEvent(Channel *channel)
    {
        bool ret = HasChannel(channel);
        if (ret == true)
        {
            // 存在就修改
            Update(channel, EPOLL_CTL_MOD);
            return;
        }
        // 如果不存在就增加
        channels_.insert({channel->GetFd(), channel});

        Update(channel, EPOLL_CTL_ADD);
    }

    // 删除事件的监控
    void RemoveEvent(Channel *channel)
    {
        int fd = channel->GetFd();
        auto it = channels_.find(fd);
        if (it != channels_.end())
        {
            // 将channel对象移除我们的监控
            channels_.erase(it);
        }
        // 移除epoll红黑树中的事件
        Update(channel, EPOLL_CTL_DEL);
    }

    // 开始监听，获取活跃的事件
    void Poll(std::vector<Channel *> *actives)
    {
        //-1代表阻塞监听事件
         //  int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);\
        timeout以毫秒为单位，代表监听多久返回,我们这里设置-1，代表不监听到事件就绪就不返回

        int n = epoll_wait(epfd_, events_, MAX_EPOLL_SIZE, -1);
        if (n < 0)
        {
            // 收到中断信号
            if (errno == EINTR)
            {
                return;
            }
            // 监听出错,退出程序
            ERR_LOG("EPOLL WAIT FAILED!! %s", strerror(errno));
            abort();
        }

        // 对epoll就绪事件进行设置
        for (int i = 0; i < n; i++)
        {
            int fd = events_[i].data.fd;
            uint32_t event = events_[i].events;

            // 找到channel对象填写对应的就绪事件
            auto it = channels_.find(fd);
            assert(it != channels_.end());

            // 将就绪事件写入对应的channel
            it->second->SetTriEvents(event);
            actives->push_back(it->second);
        }
    }
};

using TimeTask = std::function<void()>;
using WeakPtrDeleteTask = std::function<void()>;

// 用类来封装定时任务
// 1.是为了对象销毁时自动调用析构，一个超时时间点会有多条定时任务，一个clear将对象全部清除，定时任务不就一下完成了
// 2.为后面刷新、取消任务做设计
class TimerTask
{
private:
    // 每个定时任务得id
    uint64_t clock_id_;
    // 每个定时任务得时间
    uint32_t time_out_;
    // 超时时，定时任务是否需要完成
    bool cancle_;
    // 定时任务得回调，超时了应该做啥
    TimeTask time_task_cb_;
    // weak_ptr销毁得回调，定时任务不在了那么哈希表中也不需要存储weak_ptr了。
    WeakPtrDeleteTask weak_ptr_delete_cb_;

public:
    TimerTask(uint64_t id, uint32_t delay, TimeTask cb) : clock_id_(id), time_out_(delay), cancle_(false), time_task_cb_(cb)
    {
    }
    ~TimerTask()
    {
        if (cancle_ == false)
        {
            time_task_cb_();
        }
        weak_ptr_delete_cb_();
    }

    // weak_ptr的销毁时时间轮来设置得，不用用户传入。
    void SetWeakDeleteCallback(const WeakPtrDeleteTask& cb) { weak_ptr_delete_cb_ = cb; }

    int DeleyTime()
    {
        return time_out_;
    }

    void CancleTask()
    {
        cancle_ = true;
    }
};

class EventLoop;

#define MAX_TIME_OUT 60

class TimerWheel
{
    // 定义一个shared_ptr管理TimerTask对象的类型，后面用来
    using SharedptrTimerTask = std::shared_ptr<TimerTask>;
    // 定义一个weak_ptr管理TimerTask对象的类型，
    using WeakptrTimerTask = std::weak_ptr<TimerTask>;

private:
    // 时间轮超时最大设定值,表盘最大数量---其实就是最大延迟时间
    int capacity_;
    // 秒针,当前的秒针，走到哪里释放哪里，释放哪里，就相当于执行哪里的任务
    int tick_;
    // 存储定时任务对象得容器（二维）存储的是shaer_ptr包装的对象
    std::vector<std::vector<SharedptrTimerTask>> timer_wheel_;

    // 这里用weak_ptr是为了获取我们的任务对象，刷新任务时需要用到
    // 不用shared_ptr的原因：如果对同一对象管理，我们shared_ptr对象销毁时需要引用计数为0才能调用管理对象的析构，但是我们的哈希表里的share_ptr对象需要管理对象的析构才能销毁自己。
    // 每个定时任务对象和任务id的映射。weak_ptr包装的
    std::unordered_map<uint64_t, WeakptrTimerTask> times_;

    // 需要一个timerfd管控计时器
    int timerfd_;
    // eventloop对象
    EventLoop *loop_;
    // 因为要监控计时器的读事件，因此需要一个channel对象管理监听事件
    std::unique_ptr<Channel> timer_channel_;

private:
    static int CreateTimerfd()
    {
        // 创建了一个计时器对象，并没有启动
        // 以系统启动时间递增的一个基准值
        int timerfd = timerfd_create(CLOCK_MONOTONIC, 0); // 0表示阻塞读
        if (timerfd < 0)
        {
            perror("TIMERFD CREATE FAILED!!");
            abort();
        }

        // 启动对象
        // 启动对象之前需要设置我们的时间
        struct itimerspec newt;
        // 第一次超时时间
        newt.it_value.tv_sec = 1;
        newt.it_value.tv_nsec = 0;

        // 第一次之后的超时时间
        newt.it_interval.tv_sec = 1;
        newt.it_interval.tv_nsec = 0;

        // 设置超时时间，第二个参数为获取前一次设置，一般不要
        int n = timerfd_settime(timerfd, 0, &newt, nullptr);
        if (n < 0)
        {
            perror("TIMERFD SETTIME FAILED!!");
            abort();
        }

        return timerfd;
    }

    uint64_t ReadTimer()
    {
        uint64_t times;
        int n = read(timerfd_, &times, sizeof(times));
        if (n <= 0)
        {
            if (errno == EINTR || errno == EAGAIN)
            {
                return 0;
            }
            ERR_LOG("TIMER READ FAILED!!");
            abort();
        }
        return times;
    }

    // 1s执行一次
    void RunTask()
    {
        // 秒针+1
        tick_ = (tick_ + 1) % capacity_;

        // 清楚该超时时间点的所有定时任务对象
        timer_wheel_[tick_].clear();
    }

    // 读就绪事件的回调函数
    void OnTimeCallBack()
    {
        uint64_t times = ReadTimer();
        // 读取到几就代表过了几秒，就要执行几次时间轮任务
        for (uint64_t i = 0; i < times; i++)
        {
            RunTask();
        }
    }

    void TimerTaskAddInLoop(uint64_t id, uint32_t delay, TimeTask cb)
    {
        // 判断设置的时间是否正确
        if (delay <= 0 || delay >= 60)
            return;

        TimerTask *task = new TimerTask(id, delay, cb);

        SharedptrTimerTask spt(task);
        WeakptrTimerTask wpt(spt);

        timer_wheel_[(tick_ + delay) % capacity_].push_back(spt);

        // 传入weak_ptr销毁的回调函数对象
        spt->SetWeakDeleteCallback(std::bind(&TimerWheel::RemoveWeakptr, this, id));

        times_[id] = wpt;
    }

    void RemoveWeakptr(uint64_t id)
    {
        auto it = times_.find(id);
        if (it == times_.end())
        {
            return;
        }
        times_.erase(it);
    }

    void TimerTaskRefreshInLoop(uint64_t id)
    {
        auto it = times_.find(id);
        if (it == times_.end())
        {
            return;
        }

        SharedptrTimerTask pt = it->second.lock();
        if (pt == nullptr)
        {
            return;
        }

        int delay = pt->DeleyTime();

        // 将其重新添加进时间轮里面
        timer_wheel_[(tick_ + delay) % capacity_].push_back(pt);
    }

    void TimerTaskCancleInLoop(uint64_t id)
    {
        auto it = times_.find(id);
        if (it == times_.end())
        {
            return;
        }

        SharedptrTimerTask pt = it->second.lock();
        if (pt == nullptr)
        {
            return;
        }
        // 调用取消任务函数
        pt->CancleTask();
    }

public:
    // 定义一个最大60秒的时间轮
    // 使用capacity注意声明顺序
    TimerWheel(EventLoop *loop) : capacity_(MAX_TIME_OUT), tick_(0), timer_wheel_(capacity_),
                                  loop_(loop), timerfd_(CreateTimerfd()), timer_channel_(new Channel(loop, timerfd_))
    {
        timer_channel_->SetReadCallback(std::bind(&TimerWheel::OnTimeCallBack, this));
        timer_channel_->EnableReadListen();
    }

    ~TimerWheel()
    {
    }

    // 因为对times_的访问需要加锁，不如我们将其添加到eventloop绑定的线程中，这样就不会有线程安全的问题
    void TimerTaskAdd(uint64_t id, uint32_t delay, TimeTask cb);
    void TimerTaskRefresh(uint64_t id);
    void TimerTaskCancle(uint64_t id);
    /*这个接⼝存在线程安全问题--这个接⼝实际上不能被外界使⽤者调⽤，只能在模块内，在
对应的EventLoop线程内执⾏*/
    bool HasTimer(uint64_t id)
    {
        auto it = times_.find(id);
        if (it == times_.end())
        {
            return false;
        }
        return true;
    }
};

class EventLoop
{
private:
    // 传入的任务回调函数
    using func_t = std::function<void()>;
    // 事件fd
    int eventfd_;
    // 事件监控对象
    Poller poller;
    // 任务事件监控管理对象，eventloop销毁就跟着销毁
    std::unique_ptr<Channel> eventfd_channel_;
    // 任务队列
    std::vector<func_t> tasks_;
    // 线程id，c++11封装的，不是thread_self
    std::thread::id thread_id_;

    // 用来保证任务队列安全的锁
    std::mutex mutex_;

    // 为TimerWheel绑定EventLoop
    TimerWheel timer_wheel_;

private:
    // 创建eventfd
    static int CreateEventfd()
    {
        int efd = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);
        if (efd < 0)
        {
            ERR_LOG("EVENTFD CREATE FAILED!!");
            abort();
        }

        return efd;
    }
    // 向eventfd中写入
    void WriteEventfd()
    {
        uint64_t num = 1;
        int n = write(eventfd_, &num, sizeof(num));
        if (n < 0)
        {
            if (errno == EINTR || errno == EAGAIN)
            {
                return;
            }
            ERR_LOG("EVENTFD WRITE FAILED!!");
            abort();
        }
    }

     void ReadCallback()
    {
        uint64_t buf;
        int n = read(eventfd_, &buf, sizeof(buf));
        if (n <= 0)
        {
            // 如果被中断或者读取数据为0
            if (errno == EINTR || errno == EAGAIN)
            {
                return;
            }
            ERR_LOG("READ EVENTFD FAILED!!!");
            abort();
        }
    }


    // 执行任务队列
    void RunAllTask()
    {
        // 创建一个vector换出我们的任务
        std::vector<func_t> tmp;
        // 访问任务队列需要加锁
        {
            // 加锁，出了作用域就自动解锁
            std::unique_lock<std::mutex> lock(mutex_);
            tasks_.swap(tmp);
        }

        // 依次执行我们的任务
        for (auto &f : tmp)
        {
            f();
        }
    }

public:
    EventLoop() : eventfd_(CreateEventfd()), thread_id_(std::this_thread::get_id()),
                  eventfd_channel_(new Channel(this, eventfd_)), timer_wheel_(this)
    {
        // 为eventfd添加可读回调函数，读事件就绪调用
        eventfd_channel_->SetReadCallback(std::bind(&EventLoop::ReadCallback, this));
        // 打开eventfd的读事件监控
        eventfd_channel_->EnableReadListen();
    }

    bool HasTimer(uint64_t timerid)
    {
        return timer_wheel_.HasTimer(timerid);
    }
   
    // 将任务压入队列
    void QueueInLoop(const func_t &cb)
    {
        // 加入队列前也需要加锁，不同的线程可能都要操作
        {
            std::unique_lock<std::mutex> lock(mutex_);
            tasks_.push_back(cb);
        }
        // 向eventfd中写入数据触发读事件就绪，防止poller监控一直阻塞，而任务队列执行也就被阻塞了。
        //唤醒有可能因为没有事件就绪，而导致的epoll阻塞；
        //其实就是给eventfd写入一个数据，eventfd就会触发可读事件
        WriteEventfd();  
    }

    void AssertInLoop()
    {
        assert(thread_id_ == std::this_thread::get_id());
    }

    // 处理任务，先判断是否处于当前线程，是就执行，不是就加入
    void RunInLoop(const func_t &cb)
    {
        // 如果线程与EventLoop绑定的线程相同就执行任务
        if (IsInLoop())
        {
            cb();
            return;
        }
        // 否则加入执行队列，由对应的线程完成任务。
        else
        {
            QueueInLoop(cb);
        }
    }
    // 是否处于EventLoop对应线程中
    bool IsInLoop()
    {
        return thread_id_ == std::this_thread::get_id();
    }

    // 移除监控
    void RemoveEvent(Channel *channel)
    {
        poller.RemoveEvent(channel);
    }
    // 增加/修改监控事件
    void UpdateEvent(Channel *channel)
    {
        poller.UpdateEvent(channel);
    }
    // 开启loop(事件循环)，就是监控事件，处理事件，最后执行任务
    void Start()
    {
        while (1)
        {
            std::vector<Channel *> actives;
            // 取出活跃事件对应的channel对象
            poller.Poll(&actives);

            // 根据channel处理每个事件
            for (auto &channel : actives)
            {
                //因为在Poll中我们已经将channel对应的就绪事件设置了，调用处理函数即可,里面会根据活跃事件\
            分别调用不同的回调函数.
                channel->HandleEvents();
            }

            // 处理任务队列中的任务
            RunAllTask();
        }
    }

    void TimerTaskAdd(uint64_t id, uint32_t delay, const TimeTask &cb)
    {
        timer_wheel_.TimerTaskAdd(id, delay, cb);
    }

    void TimerTaskRefresh(uint64_t id)
    {
        timer_wheel_.TimerTaskRefresh(id);
    }

    void TimerTaskCancle(uint64_t id)
    {
        timer_wheel_.TimerTaskCancle(id);
    }
};

//DISCONECTED -- 连接关闭状态；   CONNECTING -- 连接建立成功-待处理状态
//CONNECTED -- 连接建立完成，各种设置已完成，可以通信的状态；  DISCONNECTING -- 待关闭状态
typedef enum
{
    DISCONNECTED,
    CONNECTING,
    CONNECTED,
    DISCONNECTING
} ConStatu;

class Connection;
using SharedptrCon = std::shared_ptr<Connection>;
class Connection : public std::enable_shared_from_this<Connection>
{
private:
    uint64_t con_id_; // 用来标记唯一的连接id
    // 设置timerid也需要我们的唯一id，这里就用con_id_来代替

    int sockfd_;      // 套接字描述符
    Socket socket_;   // 套接字
    EventLoop *loop_; // 连接绑定的loop
    Channel channel_; // 对套接字的事件管理

    ConStatu con_status;           // 连接的状态
    bool enable_inactive_release_; // 是否启动非活跃连接释放

    // 缓冲区
    Buffer in_buffer_;
    Buffer out_buffer_;

    // 连接的上下文
    Any context_;

    using ConnectCallback = std::function<void(const SharedptrCon &)>;
    using MessageCallback = std::function<void(const SharedptrCon &, Buffer *)>;
    using DisconnectCallback = std::function<void(const SharedptrCon &)>;
    using AnyCallback = std::function<void(const SharedptrCon &)>;
    using ServerDisconnectCallback = std::function<void(const SharedptrCon &)>;

    ConnectCallback connect_callback_;
    MessageCallback message_callback_;
    DisconnectCallback disconnect_callback_;
    AnyCallback any_callback_;

    // 我们的服务组件的连接断开回调，因为服务端需要删除本链接的信息
    ServerDisconnectCallback server_disconnect_callback_;

private:
    void HandleWrite()
    {
        ssize_t ret = socket_.SendNoneBlock(out_buffer_.ReadPosition(), out_buffer_.ReadableSize());
        if (ret < 0)
        {
            if (in_buffer_.ReadableSize() > 0)
            {
                if (message_callback_)
                    message_callback_(shared_from_this(), &in_buffer_);
            }
            Release();
            return;
        }

        out_buffer_.MoveReaderOffset(ret);
        if (out_buffer_.ReadableSize() == 0)
        {
            channel_.DisableWriteListen();
            if (con_status == DISCONNECTING)
            {
                Release();
            }
        }
    }

    void HandleRead()
    {
        char buffer[65536];
        // 从套接字中读取数据
        ssize_t ret = socket_.RecvNoneBlock(buffer, 65535);
        if (ret < 0)
        {
            // 读失败，就设置为半连接
            ShutDownInLoop();
            return;
        }

        // 写入读缓冲区
        in_buffer_.WriteAndPush(buffer, ret);
        if (in_buffer_.ReadableSize() > 0)
        {
            if (message_callback_)
                message_callback_(shared_from_this(), &in_buffer_);
        }
    }

    // 错误事件就绪
    void HandleError()
    {
        HandleDisConnect();
    }

    // 挂断事件就绪
    void HandleDisConnect()
    {
        if (in_buffer_.ReadableSize() > 0)
        {
            if (message_callback_)
                message_callback_(shared_from_this(), &in_buffer_);
        }
        Release();
    }

    void HandleAny()
    {
        // 刷新事件活跃度
        if (enable_inactive_release_ == true)
            loop_->TimerTaskRefresh(con_id_);
        // 调用用户的任意事件函数
        if (any_callback_)
            any_callback_(shared_from_this());
    }

    // 释放连接
    void ReleaseInLoop()
    {
        // 设置状态
        con_status = DISCONNECTED;
        // 删除监控
        if (socket_.GetFd() == -1)
        {
            ERR_LOG("%d",socket_.GetFd());
            ERR_LOG("%d",con_status);
        }
        channel_.RemoveListen();
        // 删除套接字
        socket_.Close();
        // 取消定时任务
        if (loop_->HasTimer(con_id_))
            CancleInactiveReleaseInLoop();

        // 调用用户回调
        if (disconnect_callback_)
            disconnect_callback_(shared_from_this());

        if (server_disconnect_callback_)
            server_disconnect_callback_(shared_from_this());
    }

    // 连接刚建立时的调用函数,连接的初始化
    void EstablishedInLoop()
    {
        assert(con_status == CONNECTING);
        // 设置状态
        con_status = CONNECTED;

        // 设置读事件监听
        channel_.EnableReadListen();

        // 调用回调
        if (connect_callback_)
            connect_callback_(shared_from_this());
    }

    // 发送数据到缓冲区
    void SendInLoop(Buffer& buf)
    {
        if (con_status == DISCONNECTED)
            return;
        out_buffer_.WriteBufferAndPush(buf);
        if (channel_.IsListenwrite() == false)
        {
            channel_.EnableWriteListen();
        }
    }

    // 半关闭连接
    void ShutDownInLoop()
    {
        // 设置状态
        con_status = DISCONNECTING;
        // 读取缓冲区处理
        if (in_buffer_.ReadableSize() > 0)
        {
            if (message_callback_)
                message_callback_(shared_from_this(), &in_buffer_);
        }

        // 如果写缓冲区还有就继续发送
        if (out_buffer_.ReadableSize() > 0)
        {
            if (channel_.IsListenwrite() == false)
            {
                channel_.EnableWriteListen();
            }
        }
        // 如果写缓冲区没有数据就直接释放
        if (out_buffer_.ReadableSize() == 0)
        {
            Release();
        }
    }

    //启动非活跃连接超时释放
    void EableInactiveReleaseInLoop(int delay)
    {
        // 改变状态
        enable_inactive_release_ = true;

        // 查看是否有这个定时任务
        if (loop_->HasTimer(con_id_))
        {
            loop_->TimerTaskRefresh(con_id_);
            return;
        }
        // 没有就添加
        loop_->TimerTaskAdd(con_id_, delay, std::bind(&Connection::Release, this));
    }

    void CancleInactiveReleaseInLoop()
    {
        // 改状态
        enable_inactive_release_ = false;
        // 如果定时任务队列存在就取消
        if (loop_->HasTimer(con_id_))
        {
            loop_->TimerTaskCancle(con_id_);
        }
    }

    void UpgradeInLoop(const Any &context, ConnectCallback con_cb, MessageCallback mes_cb, DisconnectCallback dis_cb, AnyCallback any_cb, ServerDisconnectCallback svrdis_cb)
    {
        context_ = context;
        connect_callback_ = con_cb;
        message_callback_ = mes_cb;
        disconnect_callback_ = dis_cb;
        any_callback_ = any_cb;
        server_disconnect_callback_ = svrdis_cb;
    }

public: // 外部调用者的接口
    Connection(EventLoop *loop, uint64_t con_id, int sockfd) : loop_(loop), con_id_(con_id), sockfd_(sockfd), socket_(sockfd),
                                                               channel_(loop, sockfd), enable_inactive_release_(false), con_status(CONNECTING)
    {
        channel_.SetReadCallback(std::bind(&Connection::HandleRead, this));
        channel_.SetWriteCallback(std::bind(&Connection::HandleWrite, this));
        channel_.SetErrorCallback(std::bind(&Connection::HandleError, this));
        channel_.SetDisconnectCallback(std::bind(&Connection::HandleDisConnect, this));
        channel_.SetAnyCallback(std::bind(&Connection::HandleAny, this));
    }
    ~Connection()
    {
        DBG_LOG("CONNECTION RELEASE SUCCESS:%p", this);
    }
    // 获取连接id
    uint64_t GetId()
    {
        return con_id_;
    }
    // 获取套接字fd
    int GetFd()
    {
        return sockfd_;
    }
    // 获取上下文
    Any *GetContext()
    {
        return &context_;
    }
    // 设置上下文
    void SetContext(const Any &context)
    {
        context_ = context;
    }

    // 连接刚建立时的初始化
    void Established()
    {
        loop_->RunInLoop(std::bind(&Connection::EstablishedInLoop, this));
    }
    // 设置连接回调
    void SetConnectCallback(const ConnectCallback &cb)
    {
        connect_callback_ = cb;
    }

    // 设置数据处理回调
    void SetMessagetCallback(const MessageCallback &cb)
    {
        message_callback_ = cb;
    }

    // 设置断开连接回调
    void SetDisconnectCallback(const DisconnectCallback &cb)
    {
        disconnect_callback_ = cb;
    }

    // 设置连接回调
    void SetAnyCallback(const AnyCallback &cb)
    {
        any_callback_ = cb;
    }

    // 设置服务组件得断开连接回调
    void SetServerDisconnectCallback(const ServerDisconnectCallback &cb)
    {
        server_disconnect_callback_ = cb;
    }

    void Send(const char *data, size_t len) // 发送数据,发到我们的缓冲区中
    {
        // 由于传入得数据是可能临时变量，因此我们需要自己存储一份，防止最后任务队列处理时访问野指针
        Buffer buf;
        buf.WriteAndPush(data, len);
        loop_->RunInLoop(std::bind(&Connection::SendInLoop, this, buf));
    }

    void ShutDown() // 关闭连接，但是实际要判断后再做关闭
    {
        loop_->RunInLoop(std::bind(&Connection::ShutDownInLoop, this));
    }

    void Release() 
    {
        loop_->QueueInLoop(std::bind(&Connection::ReleaseInLoop, this));
    }
    void EableInactiveRelease(int sec) // 设置连接为非活跃连接释放
    {
        loop_->RunInLoop(std::bind(&Connection::EableInactiveReleaseInLoop, this, sec));
    }

    void CancleInactiveRelease() // 取消非活跃连接释放
    {
        loop_->RunInLoop(std::bind(&Connection::CancleInactiveReleaseInLoop, this));
    }

    // 更新上下文,以及各个回调函数得切换，但是这个接口不能放在任务队列中执行，必须由eventloop绑定得线程执行
    // 如果有新的事件触发，但是我们的协议还在任务队列中没有执行，则会导致使用老的协议处理数据。
    void Upgrade(const Any &context, ConnectCallback con_cb, MessageCallback mes_cb, DisconnectCallback dis_cb, AnyCallback any_cb, ServerDisconnectCallback svrdis_cb)
    {
        // 先确保是eventloop绑定得线程调用
        loop_->AssertInLoop();
        // 然后再切换上下文，切换回调函数
        loop_->RunInLoop(std::bind(&Connection::UpgradeInLoop, this, context, con_cb, mes_cb, dis_cb, any_cb, svrdis_cb));
    }
};

class Acceptor
{
private:
    EventLoop *loop_;
    Socket socket_;
    Channel channel_;

    using AcceptCallback = std::function<void(int)>;
    AcceptCallback accept_callback_;

private:
    void HandleRead()
    {
        int newfd = socket_.Accept();
        if (newfd < 0)
        {
            return;
        }

        if (accept_callback_)
            accept_callback_(newfd);
    }
    int CreateListenSocket(uint16_t port)
    {
        // 创建一个监听套接字
        bool ret = socket_.CreateServer(port);
        assert(ret == true);
        return socket_.GetFd();
    }

public:
    // 不能将读监听启动放在构造函数，应放到回调函数设置之后
    // 如果一个读监听启动但是回调却没有设置，就会造成新连接没人管理，导致资源泄漏
    Acceptor(EventLoop *loop, uint16_t port) : loop_(loop), socket_(CreateListenSocket(port)),
                                               channel_(loop, socket_.GetFd())
    {
        channel_.SetReadCallback(std::bind(&Acceptor::HandleRead, this));
    }

    // 获新连接后调用的回调函数
    void SetAcceptCallback(const AcceptCallback &cb)
    {
        accept_callback_ = cb;
    }

    void EnableRead()
    {
        channel_.EnableReadListen();
    }
};

class LoopThread
{
private:
    // 创建的线程
    std::thread thread_;
    // 线程对应的eventloop，必须要在对应得线程中实例化，因此是指针
    // 因为实例化时会默认绑定我们的线程，如果不是指针，那所有eventloop就全部绑定得主线程，在后面去改可能会引发错误.
    EventLoop *loop_;
    // 互斥锁
    std::mutex mutex_;
    // 条件变量
    std::condition_variable cond_;

    // 线程得入口函数
    void ThreadEntry()
    {
        // 创建一个EventLoop
        EventLoop loop;
        {
            // 加锁
            std::unique_lock<std::mutex> lock(mutex_);
            loop_ = &loop;
            // 唤醒等待的条件变量
            cond_.notify_all();
        }
        // 运行eventloop,开启事件循环
        loop.Start();
    }

public:
    LoopThread() : thread_(&LoopThread::ThreadEntry, this), loop_(nullptr)
    {
    }
    // 获取线程对应的eventloop
    EventLoop *GetLoop()
    {
        EventLoop *loop = nullptr;
        {
            // 加锁
            std::unique_lock<std::mutex> lock(mutex_);
            // 条件变量在lock下等，等待的条件是loop_不为空，为空就阻塞等待。
            cond_.wait(lock, [&]()
                       { return loop_ != nullptr; });
            loop = loop_;
        }
        return loop;
    }
};

class LoopThreadPool
{
private:
    // 从属线程得数量
    int thread_count_;
    // 主线程得eventloop
    EventLoop *main_loop_;
    // 下一loop得下标
    int loop_index_;
    // 管理loopthread
    std::vector<LoopThread *> threads_;
    // 管理eventloop
    std::vector<EventLoop *> loops_;

public:
    LoopThreadPool(EventLoop *loop) : thread_count_(0), main_loop_(loop), loop_index_(0)
    {
    }
    // 设置从属线程数量
    void SetThreadCount(int count)
    {
        thread_count_ = count;
    }
    // 创建从属线程绑定eventloop
    void Create()
    {
        if (thread_count_ > 0)
        {
            // 创建loopthread
            threads_.resize(thread_count_);
            // 管理从属线程绑定得eventloop
            loops_.resize(thread_count_);
            for (int i = 0; i < thread_count_; i++)
            {
                threads_[i] = new LoopThread();
                loops_[i] = threads_[i]->GetLoop();
            }
        }
    }
    // 获取一个绑定了线程得eventloop
    EventLoop *GetLoop()
    {
        if (thread_count_ == 0)
            return main_loop_;

        // RR轮转进行分配
        EventLoop *loop = loops_[loop_index_];
        loop_index_ = (loop_index_ + 1) % thread_count_;

        return loop;
    }
};

class TcpServer
{
private:
    // conid和timerid
    uint64_t next_id_;
    // 非活跃超时连接得存活时间
    int timeout_;
    // 是否启动非活跃连接超时
    bool enable_inactive_release;
    // 主线程得eventloop
    EventLoop main_loop_;
    // 绑定得端口号
    uint16_t port_;
    // 监听套接字
    Acceptor acceptor_;
    // eventloop线程池，为连接分配loop，启动事件得监听
    LoopThreadPool loop_pool_;
    // 对所有连接得管理
    std::unordered_map<uint64_t, SharedptrCon> conns_;

    using ConnectCallback = std::function<void(const SharedptrCon &)>;
    using MessageCallback = std::function<void(const SharedptrCon &, Buffer *)>;
    using DisconnectCallback = std::function<void(const SharedptrCon &)>;
    using AnyCallback = std::function<void(const SharedptrCon &)>;

    using Funct = std::function<void()>;

    ConnectCallback connect_callback_;
    MessageCallback message_callback_;
    DisconnectCallback disconnect_callback_;
    AnyCallback any_callback_;

private:
    // 移除tcp服务端的连接回调
    void RemoveConnetcionInLoop(const SharedptrCon &con)
    {
        uint64_t con_id = con->GetId();
        auto it = conns_.find(con_id);
        if (it != conns_.end())
        {
            conns_.erase(it);
        }
    }

    // 新连接的服务器关闭连接的回调函数
    void RemoveConnetcion(const SharedptrCon &con)
    {
        main_loop_.RunInLoop(std::bind(&TcpServer::RemoveConnetcionInLoop, this, con));
    }

    // acceptor获取到新连接后调用的回调函数
    void NewConnection(int newfd)
    {
        next_id_++;
        // 创建新的connection对象
        SharedptrCon con(new Connection(loop_pool_.GetLoop(), next_id_, newfd));

        con->SetConnectCallback(connect_callback_);
        con->SetMessagetCallback(message_callback_);
        con->SetDisconnectCallback(disconnect_callback_);
        con->SetAnyCallback(any_callback_);
        con->SetServerDisconnectCallback(std::bind(&TcpServer::RemoveConnetcion, this, std::placeholders::_1));

        con->Established();
        if (enable_inactive_release == true)
            con->EableInactiveRelease(timeout_);
        conns_.insert(std::make_pair(next_id_, con));
    }

    void TimerTaskAddInLoop(int timeout, const Funct &cb)
    {
        next_id_++;
        main_loop_.TimerTaskAdd(next_id_, timeout, cb);
    }

public:
    TcpServer(uint16_t port) : next_id_(0), enable_inactive_release(false), port_(port), acceptor_(&main_loop_, port_), loop_pool_(&main_loop_)
    {
        // 设置监听套接字新连接回调函数
        acceptor_.SetAcceptCallback(std::bind(&TcpServer::NewConnection, this, std::placeholders::_1));
        // 启动监听套接字的读事件监听
        acceptor_.EnableRead();
    }

    // 设置连接回调
    void SetConnectCallback(const ConnectCallback &cb)
    {
        connect_callback_ = cb;
    }

    // 设置数据处理回调
    void SetMessagetCallback(const MessageCallback &cb)
    {
        message_callback_ = cb;
    }

    // 设置断开连接回调
    void SetDisconnectCallback(const DisconnectCallback &cb)
    {
        disconnect_callback_ = cb;
    }

    // 设置连接回调
    void SetAnyCallback(const AnyCallback &cb)
    {
        any_callback_ = cb;
    }

    // 设置从属线程数量
    void SetThreadCount(int count)
    {
        loop_pool_.SetThreadCount(count);
    }

    // 是否启动非活跃链接释放
    void EnableInactiveRelease(int timeout)
    {
        timeout_ = timeout;
        enable_inactive_release = true;
    }

    // 添加定时任务
    void TimerTaskAdd(int timeout, const Funct &cb)
    {
        main_loop_.RunInLoop(std::bind(&TcpServer::TimerTaskAddInLoop, this, timeout, cb));
    }

    // 启动服务
    void Start()
    {
        // 创建从属线程,必须在线程数量设置好以后才调用
        loop_pool_.Create();
        // 启动eventloop事件监听
        main_loop_.Start();
    }
};

void Channel::RemoveListen()
{
    loop_->RemoveEvent(this);
}
void Channel::UpdateListen()
{
    loop_->UpdateEvent(this);
}

void TimerWheel::TimerTaskAdd(uint64_t id, uint32_t delay, TimeTask cb)
{
    loop_->RunInLoop(std::bind(&TimerWheel::TimerTaskAddInLoop, this, id, delay, cb));
}

void TimerWheel::TimerTaskRefresh(uint64_t id)
{
    loop_->RunInLoop(std::bind(&TimerWheel::TimerTaskRefreshInLoop, this, id));
}

void TimerWheel::TimerTaskCancle(uint64_t id)
{
    loop_->RunInLoop(std::bind(&TimerWheel::TimerTaskCancleInLoop, this, id));
}

// 防止因为连接关闭，发送数据失败时，信号被发送而中断了程序
class NetWork
{
public:
    NetWork()
    {
        DBG_LOG("SIGPIPE IS SIG_IGN")
        signal(SIGPIPE, SIG_IGN);
    }
};

static NetWork network;